﻿#pragma once

#include "Event/MouseEvent.h"
#include "Containers/ScriptDelegateImplement.h"
#include "Widgets/Widget.h"

#include "Framework/Tickable.h"
#include "SelectionGroup.h"
#include "MouseCursorType.h"
#include "MouseDrag.h"
#include "MouseWidget.m.h"


class RKeyboardWidget;

//enable parent widget response to mouse
RCLASS()
class WHENGINE_API RMouseWidget : public RWidget
{
    ROBJECT
public:    
    RMouseWidget();

    virtual void FirstTimeInitializeObject() override;

    virtual SColor GetDebugBoxColor() override { return SColor(1,1,0,1); };

    virtual void Tick(float DeltaSeconds) override;

    virtual void Unregister() override;

    bool ProcessMouseEvent(const SMouseButtonEvent& MouseEvent);
protected:
    bool ProcessMouseEventInner(const SMouseButtonEvent& MouseEvent);
public:
    //get mouse position in Widget space
    SVec2 GetMousePositionInContent();

    RFIELD()
    TScriptDelegate<bool(const SMouseButtonEvent&)> OnClicked;  //imply comsume mouse button press event
    
    RFIELD()
    TScriptDelegate<bool(const SMouseButtonEvent&)> OnDoubleClicked;  //imply comsume mouse button press event
    
    RFIELD()
    TScriptDelegate<bool(const SMouseButtonEvent&)> OnWheeled;

    //被盖住的控件是否可以响应鼠标事件
    //如果为true，将强制消耗所有鼠标事件，避免被盖住的控件响应鼠标事件
    RFIELD()
    TWidgetAttribute<bool> bPreventCovoredWidgetResponse=true;

    //鼠标按下事件
    //返回值表示是否消耗了事件
    //当鼠标按下时会自动检测是否需要开始拖拽
    //如果消耗了该事件，将父控件无法响应鼠标按下事件也无法拖拽
    RFIELD()
    TScriptDelegate<bool(const SMouseButtonEvent&)> OnPressed;
    
    RFIELD()
    TScriptDelegate<bool(const SMouseButtonEvent&)> OnReleased;

    RFIELD()
    TScriptDelegate<bool(const SMouseButtonEvent&)> OnMoved;

    RFIELD()
    TScriptDelegate<void()> OnEntered;
    
    RFIELD()
    TScriptDelegate<void()> OnExited;

    RFIELD()
    TScriptDelegate<bool(const SMouseButtonEvent&)> OnFileDropped;

    void NotifyEntered()
    {
        OnEntered.Broadcast();
        bIsHovered=true;
    }

    void NotifyExited()
    {
        OnExited.Broadcast();
        bIsHovered=false;
    }

    bool IsHovered() const
    {
        return bIsHovered;
    }
    
    RFIELD()
    TSharedObjectPtr<RMouseDrag> Drag;
    
    //give mouse widget a Id for debug
    //Id is ordered in hold grid sequence
    int32_t DebugMouseWidgetID=-1;
protected:
    bool bIsHovered=false;

public:
    //mouse cursor shape when drag and hovor
    TWidgetAttribute<EMouseCursorType> CursorShape=EMouseCursorType::Arrow;

public:
    void ExitSelectionGroup();

    bool IsInSelectionGroup();
    
    //@SelectTarget Widget to present selection effect
    //@Group   Selection group,defined selection behavior
    void JoinSelectionGroup(RWidgetWeakPtr SelectTarget,std::shared_ptr<CMouseSelectionGroup> Group);
protected:
    TOptional<CMouseSelectionGroupItem> Selection;
    bool bIsHoldGrid=false;

public:
    //鼠标点击时自动聚焦的键盘控件
    TWeakObjectPtr<RKeyboardWidget> AutoFocusTarget;
    //鼠标点击时自动聚焦的键盘控件是否消耗鼠标点击事件
    //bool bAutoFocusConsumesEvent=true;

};